//
// Created by wangheng on 2018/8/23.
//

#ifndef TEST11_SOCKET_H
#define TEST11_SOCKET_H

// JNI
#include <jni.h>
// NULL
#include <stdio.h>
// va_list vsnprintf
#include <stdarg.h>
// error no
#include <error.h>

// socket,bind,getsocketname,listen,accept,recv,send,connect
#include <sys/types.h>
#include <sys/socket.h>

// sockaddr_un
#include <sys/un.h>

// htons,sockaddr_in
#include <netinet/in.h>

// inet_ntop
#include <arpa/inet.h>

// close,unlink
#include <unistd.h>

// offsetof
#include <stddef.h>
#include <string.h>
#include <errno.h>

#include "my_log.h"

// 最大日志消息长度
#define MAX_LOG_MESSAGE_LENGTH 256

// 最大缓冲区大小
#define MAX_BUFFER_SIZE 80

static void ThrowException(JNIEnv *env, const char *name, const char* message) {
    jclass clazz = env->FindClass(name);
    if(NULL != clazz){
        env->ThrowNew(clazz,message);
        env->DeleteLocalRef(clazz);
    }
}

static void ThrowErrorNoException(JNIEnv *env, const char* clazzName, int errorNo){
    char buffer[MAX_LOG_MESSAGE_LENGTH];
    if(-1 == strerror_r(errorNo,buffer,MAX_LOG_MESSAGE_LENGTH)){
        strerror_r(errno,buffer,MAX_LOG_MESSAGE_LENGTH);
    }
    ThrowException(env,clazzName,buffer);
}

static void LogMessage(JNIEnv *env,jobject obj,const char *format,...){
    // 缓存方法ID
    static jmethodID methodId = NULL;
    // 如果缓存的方法ID为NULL
    if(NULL == methodId){
        jclass  clazz = env->GetObjectClass(obj);
        methodId = env->GetMethodID(clazz,"logMessage","(Ljava/lang/String;)V");
        env->DeleteLocalRef(clazz);
    }

    if(NULL != methodId){
        char buffer[MAX_LOG_MESSAGE_LENGTH];
        va_list ap;
        va_start(ap,format);
        vsnprintf(buffer,MAX_LOG_MESSAGE_LENGTH,format,ap);

        // 将缓冲区转换为java字符串
        jstring message = env->NewStringUTF(buffer);
        if(NULL != message){
            env->CallVoidMethod(obj,methodId,message);
            env->DeleteLocalRef(message);
        }
    }
}


#endif //TEST11_SOCKET_H
